package com.jse.jakarta;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Map;

import com.jse.Fs;
import com.jse.Js;
import com.jse.Jse;
import com.jse.Lang;
import com.jse.Log;
import com.jse.Strings;
import com.jse.jdbc.Pager;
import com.jse.json.Json;
import com.jse.web.Action;
import com.jse.web.View;
import com.jse.web.Web;

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class JseServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	
	private final static Log log=Log.get("jseservlet");
	private RequestDispatcher staticDispatcher;
	
	@Override
	public void init(ServletConfig conf) throws ServletException {
		staticDispatcher=conf.getServletContext().getNamedDispatcher("default");
		try {
			Web.init();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {
		req.setCharacterEncoding(Jse.encoding);
		resp.setCharacterEncoding(Jse.encoding);
		Tbl tbl=new Tbl(req, resp);
		if(staticDispatcher!=null&&Web.isStatic(tbl.getPath(),tbl.getSuffix())) {//静态
			staticDispatcher.forward(req,resp);return;
		}
		Action.service(tbl);

//		ScopedValue.runWhere(Web.RQS,tbl,()->{
//			if(!Web.filter(tbl,true))return;//true已被过滤
//			long starttime=System.currentTimeMillis();
//			int status=200;
//			try {
//				String mapping=Web.mapping(url, suffix, tbl);
//				if(url.startsWith("/jse")){
//					jse(tbl,url,suffix);
//					return;
//				}
////				Object reg=Web.REGEX_FUNS.isEmpty()?null:Web.REGEX_FUNS.keySet().parallelStream().filter(x->Jse.MATCHER.match(x,mapping)).findAny().get();
////				if(Web.FIXED_FUNS.containsKey(mapping)){//固定映射匹配
////					var t=Web.FIXED_FUNS.get(mapping);
////					View.ret.render(tbl,Js.cFun(t.a(),t.b(),t.c(),"main",Web.tbl(req,resp,url),req,resp));
////				}else if(Web.REGEX_FUNS.containsKey(reg)) {
////					var t=Web.REGEX_FUNS.get(mapping);
////					View.ret.render(tbl,Js.cFun(t.a(),t.b(),t.c(),"main",Web.tbl(req,resp,url),req,resp));
////				}else 
//				if("vue".equals(suffix)){
//					vue(tbl,url,suffix);
//				}else if("".equals(suffix)||"html".equals(suffix)){//后缀空
//					empty(tbl,url,suffix);
//				}else {
//					var webapp=Jse.webapp(req.getServerName());
//					var p=Path.of(webapp,url);
//					if(Files.exists(p)) {
//						staticDispatcher.forward(req,resp);return;
//					}
//					var jspath=Jse.jspath(req.getServerName());
//					var js=Path.of(jspath,mapping+".js");
//					if(Files.exists(js)){
//						View.ret.render(tbl,Js.cFun(js,suffix,req,resp));
//					}
//				}
//				Web.filter(tbl,false);//执行后置处理
//				if(!resp.isCommitted()) {//还没有flush处理 可以继续out
//					resp.flushBuffer();
//					//System.out.println(url+" not flush!"+resp.getContentType());
//	    		}
//			} catch (Exception e) {
//				status=500;
//				e.printStackTrace();
//				if(!resp.isCommitted()) {
//					if(e.getCause()==null) {
//						try {
//							View.err.render(tbl,"runtimeExecption:"+e.getMessage());
//						} catch (IOException e1) {
//							throw new RuntimeException(e1);
//						}
//					}else {
//						try {
//							View.err.render(tbl,e.getCause().getClass().getSimpleName()+":"+e.getMessage());
//						} catch (IOException e1) {
//							throw new RuntimeException(e1);
//						}
//					}
//				}
//			}finally {
//				log.info("%s:%d %s\t%dms",req.getMethod(),status,req.getServletPath(),(System.currentTimeMillis()-starttime));
//			}
//		});
		
	}
	
	private void jse(Tbl tbl,String url,String suffix) throws ServletException, IOException {//默认空后缀
		if(url.equals("/jse")) {
			Js.execute(Fs.read(Jse.jspath()+"/jse.js"));
			View.text.render(tbl,"jse.js init.");
		}else if(url.equals("/jse/up")) {
			View.json.render(tbl,Json.toJson(tbl));
		}else if(url.equals("/jse/code")) {//code环境
			View.html.render(tbl,tbl);
		}else if(url.equals("/jse/log")) {//日志
			View.html.render(tbl,tbl);
		}else if(url.equals("/jse/gitee")) {//gitee
			View.json.render(tbl,Js.fun("gitee",tbl));
		}
		else if(url.startsWith("/jse/captcha")) {//暂时简单实现
			var code=url.substring(12);
			if(code.length()>1){code=code.substring(1);}
			else code=tbl.get("code").toString();
			View.captcha.render(tbl,code);
		}
	}
	
	private void empty(Tbl tbl,String url,String suffix) throws ServletException, IOException {//默认空后缀
		var jspath=Jse.jspath(tbl.getServerName());
		String mapping=Web.mapping(url,suffix,tbl);//处理/id
		tbl.setAttribute("p",tbl);
		var webapp=Jse.webapp(tbl.getServerName());
		var js=Path.of(jspath+mapping+".js");
		Object obj=null;
		if(Files.exists(js)) {
			try {
				obj=ScopedValue.where(Web.RQS,tbl)
				.call(()->{return Js.cFun(js,"main",tbl);});
			} catch (Exception e) {throw new RuntimeException(e);}
		}
		var ht=Lang.def(tbl.getAttribute("@page"),mapping+".html");
		var htm=webapp+ht;
		var htmm=webapp+"/m"+ht;//手机端页面
		if(obj instanceof View v)v.render(tbl,null);
		else if(obj instanceof String s) {
			View.str.render(tbl,s);
		}else if(Files.exists(Path.of(htm))) {
			tbl.setAttribute("obj",obj);View.tpl.render(tbl,htm);
		}else if(Lang.isMobile(tbl.getHeader("user-agent"))&&Files.exists(Path.of(htmm))) {
			tbl.setAttribute("obj",obj);View.tpl.render(tbl,htmm);
		}else if(Files.exists(Path.of(jspath,mapping+".vue"))) {
			if(Files.exists(Path.of(jspath,"vue.html"))) {
				View.tpl.render(tbl,Jse.jspath+"/vue.html");
			}else {
				var s=Fs.readString(jspath,mapping+".vue",Map.of("tpl","js","p",tbl));
				View.text.render(tbl,s);
			}
		}else if(Files.exists(Path.of(webapp,mapping+".vue"))) {
			var s=Fs.readString(webapp,mapping+".vue",Map.of("tpl","js","p",tbl));
			View.text.render(tbl,s);
		}else if(Files.exists(Path.of(jspath+mapping+".html"))) {
			View.tpl.render(tbl,jspath+mapping+".html");
		}
		else if(obj instanceof Map||obj instanceof Collection||obj instanceof Pager) {
			View.json.render(tbl, obj);
		}else if(obj instanceof String s) {
			View.str.render(tbl,s);
		}
		else {
			View.not.render(tbl,null);
		}
	}
	private void vue(Tbl tbl,String url,String suffix) throws ServletException, IOException {//处理vue
		String mapping=Web.mapping(url,suffix,tbl);//处理/id
		var jspath=Jse.jspath(tbl.getServerName());
		var webapp=Jse.webapp(tbl.getServerName());
		var vue=Path.of(jspath,mapping.concat(".vue"));
		if(Files.exists(vue)) {
			var s=Fs.readString(jspath,mapping.concat(".vue"),Map.of("tpl","js","p",tbl));
			View.text.render(tbl,s);
		}
		vue=Path.of(webapp,mapping+".vue");
		if(Files.exists(vue)){
			var s=Fs.readString(webapp,mapping.concat(".vue"),Map.of("tpl","js","p",tbl));
			View.text.render(tbl,s);
		}
	}
	
	public static void main(String[] args) {
		System.out.println("/xaa/xx".replaceAll("/$","/index"));
	}
}
